using System;
using System.Drawing;
using System.Windows.Forms;
using System.Collections.Generic;
using System.Reflection;

using SBPweb.Modules.Modularity;
using SBPweb.Localization;

namespace SBPweb.Presentation.Windows.Forms.Host.Controls
{
    public partial class SplashPanel : UserControl
    {
        #region Private fields

        private string mText = string.Empty;
        private bool mShowCredits;
        private List<string> pNames = new List<string>();
        private List<string> pVersions = new List<string>();

        #endregion

		#region Delegates

		protected delegate void Loader_ModuleLoadedHandler(object sender, ModuleEventArgs e);
        
		#endregion

		#region Constructor logic

		public SplashPanel()
        {
            InitializeComponent();
            InitializeStrings();
            InitializeEvents();

			LocalizationExtender.OnInvalidatingControls += new EventHandler(LocalizationExtender_OnInvalidatingControls);
        }

        public void InitializeStrings()
        {
			lProcessTrace.Text = mText = string.Empty;

			lApplicationTitle.Text = Properties.Settings.Default.ApplicationTitle;
            lApplicationVersion.Text = "v" + Application.ProductVersion;

			if (!pNames.Contains(Properties.Settings.Default.ApplicationHostName))
			{
				pNames.Add(Properties.Settings.Default.ApplicationHostName);
				pVersions.Add(Application.ProductVersion);
			}

			if (this.ParentForm != null)
			{
				this.ParentForm.Text = LocalizationExtender.GetString("tsmiAboutText");
			}

            for (int i = 0; i < pNames.Count; i++)
            {
				try
				{
					AddSplashTraceMessage(String.Format(Program.Resources.GetString("ModuleLoadString"), pNames[i], pVersions[i]));
				}
				catch (Exception ex)
				{
					Program.LogManager.WriteError(this, string.Format("Cannot add trace message: {0}", ex), "General");
				}
            }
        }

        public void InitializeEvents()
        {
            Program.Loader.ModuleLoaded += new EventHandler<ModuleEventArgs>(Loader_ModuleLoaded);
			Program.Loader.ModuleUnloading += new EventHandler<ModuleEventArgs>(Loader_ModuleUnloading);
		}

		#endregion

		#region Events

		private void lProcessTrace_MouseClick(object sender, MouseEventArgs e)
		{
			switch (e.Button)
			{
				case MouseButtons.Left:
					if (mShowCredits = !mShowCredits)
					{
						lProcessTrace.Text = mText;
					}
					else
					{
						lProcessTrace.Text = Program.Resources.GetString("Credits");
					}
					break;
				case MouseButtons.Right:
					System.Windows.Forms.Clipboard.SetText(string.Format("{0}\n{1}", lApplicationVersion.Text, mText));
					break;
			}
		}

		private void LocalizationExtender_OnInvalidatingControls(object sender, EventArgs e)
		{
			InitializeStrings();
		}

		#endregion

		#region Private methods

		private int GetSpecifiedCharCount(string s, char c)
		{
			int count = 0;

			for (int i = 0; i < s.Length; i++)
			{
				if (s[i] == c)
				{
					count++;
				}
			}

			return count;
		}

		#endregion

		#region Internal methods

		internal void AddSplashTraceMessage(string msg)
		{
			mText += msg + "\n";
			lProcessTrace.Text = mText;

			if (lProcessTrace.Size.Height <= 80 + lProcessTrace.Font.Height * GetSpecifiedCharCount(lProcessTrace.Text, '\n'))
			{
				this.Size = new Size(this.Size.Width, this.Size.Height + 10);
			}

			this.BringToFront();
			this.Refresh();
			Application.DoEvents();
		}

		#endregion

		#region Protected methods

		protected override void OnPaint(PaintEventArgs e)
        {
            e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
            e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
            base.OnPaint(e);
        }

		protected void Loader_ModuleLoaded(object sender, ModuleEventArgs e)
        {
			if (this.InvokeRequired)
			{
				this.Invoke(new Loader_ModuleLoadedHandler(Loader_ModuleLoaded), sender, e);
				return;
			}

            string pattern = ".Modules.";
            string name = string.Format("{0}{1}", Properties.Settings.Default.PatternOfModules.Split("*".ToCharArray())[0], e.Module.Name.Substring(e.Module.Name.IndexOf(pattern) + pattern.Length));
            string version = e.Module.Version.ToString();
            pNames.Add(name);
            pVersions.Add(version);
			try
			{
				AddSplashTraceMessage(String.Format(Program.Resources.GetString("ModuleLoadString"), name, version));
			}
			catch (Exception ex)
			{
				Program.LogManager.WriteError(this, string.Format("Cannot add trace message: {0}", ex), "General");
			}
		}

		private void Loader_ModuleUnloading(object sender, ModuleEventArgs e)
		{
			if (this.InvokeRequired)
			{
				this.Invoke(new Loader_ModuleLoadedHandler(Loader_ModuleUnloading), sender, e);
				return;
			}
			string pattern = ".Modules.";
			string name = string.Format("{0}{1}", Properties.Settings.Default.PatternOfModules.Split("*".ToCharArray())[0], e.Module.Name.Substring(e.Module.Name.IndexOf(pattern) + pattern.Length));
            string version;

            if (e.Module.Version != null)
                version = e.Module.Version.ToString();
            else
                version = string.Empty;

			if (pNames.Contains(name))
			{
				pNames.Remove(name);
			}
			if (pVersions.Contains(version))
			{
				pVersions.Remove(version);
			}
			InitializeStrings();
		}

		#endregion
    }
}
